package com.edgar.barcode;

import android.app.Activity;
import android.content.Context;
import android.os.Handler;
import android.view.SurfaceHolder;

import com.edgar.barcode.camera.CameraManager;
import com.edgar.barcode.control.AmbientLightManager;
import com.edgar.barcode.control.BeepManager;
import com.edgar.barcode.decode.CaptureActivityHandler;
import com.edgar.barcode.decode.DecodeCallback;
import com.edgar.barcode.decode.InactivityTimer;

import java.io.IOException;

/**
 * Created by edgar on 2016/1/23.
 * 二维码管理
 */
public class BarcodeManager implements SurfaceHolder.Callback,DecodeCallback{

    public static final int BARCODE_MODE = 0X100;
    public static final int QRCODE_MODE = 0X200;
    public static final int ALL_MODE = 0X300;

    /**
     * 音频管理
     */
    private BeepManager mBeepManager;
    /**
     * 相机管理
     */
    private CameraManager mCameraManager;
    /**
     * 该管理器和屏幕亮度有关?
     */
    private AmbientLightManager mAmbientLightManager;

    private InactivityTimer mInactivityTimer;
    private BarcodeCallback mBarcodeCallback;
    private CaptureActivityHandler mCaptureActivityHandler;
    private volatile int mDecodeType;
    private volatile boolean hasSurface;

    public static BarcodeManager get(Activity context,BarcodeCallback barcodeCallback){
        return new BarcodeManager(context,barcodeCallback);
    }

    private BarcodeManager(Activity context,BarcodeCallback barcodeCallback){
        this.mBarcodeCallback = barcodeCallback;
        Context appContext = context.getApplicationContext();
        mCameraManager = new CameraManager(appContext);
        mBeepManager = new BeepManager(appContext);
        mInactivityTimer = new InactivityTimer(context);
        mAmbientLightManager = new AmbientLightManager(appContext);
    }

    private void initCamera(SurfaceHolder holder){
        if(holder == null){
            return;
        }
        if(mCameraManager.isOpen()){
            return;
        }
        try {
            mCameraManager.openDriver(holder);
            if(mCaptureActivityHandler == null){
                mCaptureActivityHandler = new CaptureActivityHandler(this,mBarcodeCallback);
            }
            if(mBarcodeCallback != null){
                mBarcodeCallback.onInitFinish();
            }
        } catch (IOException e) {
            mBarcodeCallback.onOpenCameraFail(e);
        }
    }

    public void setDecodeType(int decodeType){
        this.mDecodeType = decodeType;
    }

    public AmbientLightManager getAmbientLightManager(){
        return mAmbientLightManager;
    }

    public final BeepManager getBeepManager(){
        return mBeepManager;
    }

    public CameraManager getCameraManager() {
        return mCameraManager;
    }

    @Override
    public Handler getCaptureHandler() {
        return mCaptureActivityHandler;
    }

    public InactivityTimer getInactivityTimer(){
        return mInactivityTimer;
    }

    @Override
    public int getDecodeType() {
        return mDecodeType;
    }

    public void onResume(){
        mInactivityTimer.onResume();
        SurfaceHolder holder = mBarcodeCallback.getSurfaceHolder();
        if(hasSurface){
            initCamera(holder);
        } else {
            if(holder != null){
                holder.addCallback(this);
            }
        }
        mAmbientLightManager.start(mCameraManager);
    }

    public void onPause(){
        if(mCaptureActivityHandler != null){
            mCaptureActivityHandler.quitSynchronously();
            mCaptureActivityHandler = null;
        }
        mInactivityTimer.onPause();
        mAmbientLightManager.stop();
        mCameraManager.closeDriver();
        if(!hasSurface){
            SurfaceHolder holder = mBarcodeCallback.getSurfaceHolder();
            if(holder != null){
                holder.removeCallback(this);
            }
        }
    }

    public void onDestroy(){
        if(mInactivityTimer != null){
            mInactivityTimer.shutdown();
        }
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        if (!hasSurface) {
            hasSurface = true;
            initCamera(holder);
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        hasSurface = false;
    }
}